﻿///////////////////////////////////////////////////////////////////////////////
//
// This file is part of the BassDrop project
//   https://code.google.com/p/bass-drop/
//
//
// Creator:	Gergely Krajcsovszki (krajcsovszkig@hotmail.com)
// Date:	2013-10-02 10:30
//
//
// Copyright © 2013-2014. Gergely Krajcsovszki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BassDrop.Core.Common.Localization;

namespace BassDrop.Core.Common.Exceptions
{
	/// <summary>
	/// Exception thrown when multiple errors occur. It contains a list of other exceptions.
	/// </summary>
	public class CompoundException : ExceptionBase
	{
		/// <summary>
		/// Should adding a fatal error make this one fatal
		/// </summary>
		private bool m_autoAdjustFatality;

		/// <summary>
		/// This list of exceptions making up this compound exception
		/// </summary>
		private List<Exception> m_innerExceptions = new List<Exception>();
		/// <summary>
		/// Gets a copy of the list exceptions making up this compound exception
		/// </summary>
		public List<Exception> InnerExceptions
		{
			get
			{
				return new List<Exception>( m_innerExceptions );
			}
		}

		/// <summary>
		/// Creates a new Compound Exception
		/// </summary>
		/// <param name="isFatal">does this error require the program to exit (default: false)</param>
		/// <param name="autoAdjustFatality">should adding a fatal error make this one fatal (default: true)</param>
		/// <param name="firstException">if you pass an exception, it will get added to the list immediately</param>
		public CompoundException( bool isFatal = false, bool autoAdjustFatality = true, Exception firstException = null )
			: base( Strings.ExceptionCompound, null, isFatal )
		{
			m_autoAdjustFatality = autoAdjustFatality;

			if ( firstException != null )
			{
				Add( firstException );
			}
		}

		/// <summary>
		/// Adds a new exception to the list
		/// </summary>
		/// <param name="exception"></param>
		public void Add( Exception exception )
		{
			m_innerExceptions.Add( exception );
		}

		/// <summary>
		/// Adds a new BassDrop exception to the list.
		/// If the autoAdjustFatality argument of the constructor was true or left out,
		/// passing a fatal exception here makes this exception fatal as well.
		/// </summary>
		/// <param name="exception"></param>
		public void Add( ExceptionBase exception )
		{
			m_innerExceptions.Add( exception );

			if ( m_autoAdjustFatality && exception.Fatal )
			{
				Fatal = true;
			}
		}

		/// <summary>
		/// Throws this exception if it has at least one child exception
		/// </summary>
		public void ThrowIfNotEmpty()
		{
			if ( m_innerExceptions.Count > 0 )
			{
				throw this;
			}
		}

		/// <summary>
		/// Converts this exception and its children to a string
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			StringBuilder builder = new StringBuilder( base.ToString() );

			builder.Append( "\r\n\r\n" + Strings.ExceptionCompoundSublist );

			foreach ( var item in m_innerExceptions )
			{
				builder.Append( "\r\n\r\n" + item.ToString() );
			}

			return builder.ToString();
		}
	}
}
